#ifndef MESSAGESHOWAREA_H
#define MESSAGESHOWAREA_H

#include <QScrollArea>
#include <QWidget>
#include <QLabel>
#include <QPushButton>

#include "model/data.h"

// .h 文件中不宜进行 using namespace xxxx
using model::Message;

/////////////////////////////////////////////////////
/// 表示消息展示区
/////////////////////////////////////////////////////

class MessageShowArea : public QScrollArea
{
    Q_OBJECT
public:
    MessageShowArea();

    // 尾插
    void addMessage(bool isLeft, const Message& message);
    // 头插
    void addFrontMessage(bool isLeft, const Message& message);
    // 清空消息
    void clear();
    // 滚动到末尾
    void scrollToEnd();

private:
    QWidget* container;
};

/////////////////////////////////////////////////////
/// 表示一个消息元素
/// 这个里面要同时支持 文本消息，图片消息，文件消息，语音消息
/////////////////////////////////////////////////////

class MessageItem : public QWidget {
    Q_OBJECT
public:
    // isLeft 表示这个消息是否是左侧消息
    MessageItem(bool isLeft);

    // 通过工厂方法，创建 MessageItem 实例
    static MessageItem* makeMessageItem(bool isLeft, const Message& message);

    // 添加工厂函数
    static QWidget* makeTextMessageItem(bool isLeft, const QString &text);
    static QWidget* makeImageMessageItem(bool isLeft, const QString& fileId, const QByteArray& content);
    static QWidget* makeFileMessageItem(bool isLeft, const QString& fileId, const QByteArray& content, const QString& fileName);
    static QWidget* makeSpeechMessageItem(bool isLeft, const QString& fileId, const QByteArray& content);

private:
    bool isLeft;
};

/////////////////////////////////////////////////////
/// 创建类表示 "文本消息" 正文部分
/////////////////////////////////////////////////////

class MessageContentLabel : public QWidget {
    Q_OBJECT
public:
    MessageContentLabel(const QString& text, bool isLeft);

    void paintEvent(QPaintEvent* event) override;

private:
    QLabel* label;
    bool isLeft;
};

/////////////////////////////////////////////////////
/// 创建类表示 "图片消息" 正文部分
/////////////////////////////////////////////////////

class MessageImageLabel : public QWidget {
    Q_OBJECT
public:
    MessageImageLabel(const QString& fileId, const QByteArray& content, bool isLeft);

    void updateUI(const QString& fileId, const QByteArray& content);
    void paintEvent(QPaintEvent* event) override;
    void clickImage();

    bool eventFilter(QObject *obj, QEvent *e) override;

private:
    QPushButton* imageBtn;

    QString fileId;         // 该图片在服务器对应的文件 id
    QByteArray content;     // 图片的二进制数据
    bool isLeft;
};

/////////////////////////////////////////////////////
/// 创建类表示 "文件消息" 正文部分
/////////////////////////////////////////////////////
class MessageFileLabel : public QWidget {
    Q_OBJECT
public:
    MessageFileLabel(const QString& fileId, const QByteArray& content, const QString& fileName, bool isLeft);

    void updateUI(const QString& fileId, const QByteArray& fileContent);
    void paintEvent(QPaintEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;
    void saveAsFile();

private:
    QLabel* label;

    QString fileId;
    QByteArray content;
    QString fileName;
    bool isLeft;

    bool loadContentDone = false;
};

/////////////////////////////////////////////////////
/// 创建类表示 "语音消息" 正文部分
/////////////////////////////////////////////////////
class MessageSpeechLabel : public QWidget {
    Q_OBJECT
public:
    MessageSpeechLabel(const QByteArray& content, const QString& fileId, bool isLeft);

    void updateUI(const QString& fileId, const QByteArray& fileContent);
    void paintEvent(QPaintEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;

    void mousePressd();

    void contextMenuEvent(QContextMenuEvent* event) override;
    void speechConvertTextDone(const QString& fileId, const QString& text);

private:
    QLabel* label;

    QString fileId;
    QByteArray content;
    bool isLeft;

    bool loadContentDone = false;
};

#endif // MESSAGESHOWAREA_H
